package com.lry.jvm.rtda.heap;

import com.lry.jvm.classfile.constantpool.*;
import lombok.Data;

public class RuntimeConstantPool {

    private JClass jClass;
    private Object[] constants;

    public RuntimeConstantPool(JClass jClass,ConstantPool cp){
        this.jClass = jClass;
        int cpCount = cp.getConstantPoolSize();
        this.constants = new Object[cpCount];

        for(int i=1;i<cpCount;i++){
            ConstantInfo cpInfo = cp.getConstantInfos()[i];
            if(cpInfo instanceof ConstantIntegerInfo){
                ConstantIntegerInfo cpIntInfo = (ConstantIntegerInfo) cpInfo;
                constants[i] = cpIntInfo.getValue();
            }else if(cpInfo instanceof ConstantFloatInfo){
                ConstantFloatInfo cpIntInfo = (ConstantFloatInfo) cpInfo;
                constants[i] = cpIntInfo.getValue();
            }else if(cpInfo instanceof ConstantLongInfo){
                ConstantLongInfo cpIntInfo = (ConstantLongInfo) cpInfo;
                constants[i] = cpIntInfo.getValue();
                i++;
            }else if(cpInfo instanceof ConstantDoubleInfo){
                ConstantDoubleInfo cpIntInfo = (ConstantDoubleInfo) cpInfo;
                constants[i] = cpIntInfo.getValue();
                i++;
            }else if(cpInfo instanceof ConstantStringInfo){
                ConstantStringInfo cpIntInfo = (ConstantStringInfo) cpInfo;
                constants[i] = cpIntInfo.getValue();
            }else if(cpInfo instanceof ConstantUft8Info){
                ConstantUft8Info cpIntInfo = (ConstantUft8Info) cpInfo;
                constants[i] = cpIntInfo.getValue();
            }else if(cpInfo instanceof ConstantClassInfo){
                ConstantClassInfo cpIntInfo = (ConstantClassInfo) cpInfo;
                constants[i] = new ClassRef(this,cpIntInfo);
            }else if(cpInfo instanceof ConstantFieldRefInfo){
                ConstantFieldRefInfo cpIntInfo = (ConstantFieldRefInfo) cpInfo;
                constants[i] = new FieldRef(this,cpIntInfo);
            }else if(cpInfo instanceof ConstantMethodRefInfo){
                ConstantMethodRefInfo cpIntInfo = (ConstantMethodRefInfo) cpInfo;
                constants[i] = new MethodRef(this,cpIntInfo);
            }else if(cpInfo instanceof ConstantInterfaceMethodRefInfo){
                ConstantInterfaceMethodRefInfo cpIntInfo = (ConstantInterfaceMethodRefInfo) cpInfo;
                constants[i] = new InterfaceMethodRef(this,cpIntInfo);
            }
        }

    }

    public Object getConstant(int index){
        if(index<0||index>=constants.length){
            throw new ArrayIndexOutOfBoundsException();
        }
        return constants[index];
    }

    public JClass getJClass() {
        return jClass;
    }

    public void setJClass(JClass jClass) {
        this.jClass = jClass;
    }

    public Object[] getConstants() {
        return constants;
    }

    public void setConstants(Object[] constants) {
        this.constants = constants;
    }
}
